package cn.virens.service.impl.sys;

import java.io.Serializable;
import java.util.Arrays;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import cn.virens.components.page.PageParamUser;
import cn.virens.database.common.BaseServiceImpl;
import cn.virens.database.common.mapper.ExampleJoin;
import cn.virens.database.common.mapper.ExampleWrapper;
import cn.virens.database.enums.UserType;
import cn.virens.database.mysql.mapper.sys.SysUserBindMapper;
import cn.virens.database.mysql.mapper.sys.SysUserMapper;
import cn.virens.database.mysql.model.sys.SysUser;
import cn.virens.database.mysql.model.sys.SysUserBind;
import cn.virens.exception.APIException;
import cn.virens.service.inter.sys.SysUserService;
import cn.virens.utils.PermissionUtil;

/**
 * 用户管理 - sys_user
 *
 * @author Virens
 * @since  2018-08-25 15:39:30
 */
@Service
public class SysUserServiceImpl extends BaseServiceImpl<SysUserMapper, SysUser> implements SysUserService {
	private @Autowired SysUserBindMapper mSysUserBindMapper;

	public SysUserServiceImpl() {
		super(SysUser.class);
	}

	@Override
	public SysUser insert(SysUser record) {
		throw new APIException("DISABLE_API", "Disable create the user!");
	}

	@Override
	public SysUser update(SysUser record) {
		throw new APIException("DISABLE_API", "Disable create the update!");
	}

	@Override
	@Transactional(readOnly = false)
	public int delete(Serializable... id) {
		ExampleWrapper example = ExampleWrapper.of(clazz);
		example.and().andIn("uuid", Arrays.asList(id));

		return mBaseMapper.deleteByExample(example);
	}

	@Override
	@Transactional(readOnly = false)
	public SysUser update(SysUser record, String uuid) {
		ExampleWrapper example = ExampleWrapper.of(clazz);
		example.and().andEqualTo("uuid", uuid);

		record.setCreateTime(null);
		record.setUpdateTime(DateUtil.date());

		if (mBaseMapper.updateByExampleSelective(record, example) <= 0) {
			throw new APIException("NOT_FIND", "账号不存在");
		} else {
			return record;
		}
	}

	@Override
	@Transactional(readOnly = false)
	public SysUser insert(SysUser record, SysUserBind bind) {
		record.setUuid(IdUtil.fastSimpleUUID());
		record.setCreateTime(DateUtil.date());
		record.setUpdateTime(DateUtil.date());

		if (mBaseMapper.insertSelective(record) > 0) {
			bind.setCreateTime(DateUtil.date());
			bind.setUpdateTime(DateUtil.date());
			bind.setUuid(record.getUuid());

			if (mSysUserBindMapper.insertSelective(bind) <= 0) {
				throw new APIException("ERROR", "创建用户失败!");
			} else {
				return record;
			}
		} else {
			throw new APIException("ERROR", "创建用户失败!");
		}
	}

	@Override
	public SysUser selectOne(Serializable uuid) {
		ExampleWrapper example = ExampleWrapper.of(clazz);
		example.and().andEqualTo("uuid", uuid);

		return mBaseMapper.selectOne(example);
	}

	@Override
	@Transactional(readOnly = false)
	public SysUserBind bindCheck(UserType type, String account) {
		ExampleWrapper example = ExampleWrapper.of(SysUserBind.class);
		example.excludeProperties("password");
		example.and((criteria) -> {
			criteria.andEqualTo("type", type.getKey());
			criteria.andEqualTo("account", account);
		});

		return mSysUserBindMapper.selectOne(example);
	}

	@Override
	@Transactional(readOnly = false)
	public SysUserBind bindUpdate(SysUserBind record) {
		ExampleWrapper example = ExampleWrapper.of(SysUserBind.class);
		example.and().andEqualTo("uuid", record.getUuid());

		record.setUpdateTime(DateUtil.date());
		record.setAccount(null);
		record.setType(null);
		record.setUuid(null);

		if (mSysUserBindMapper.updateByExampleSelective(record, example) <= 0) {
			throw new APIException("NOT_FIND", "账号不存在");
		} else {
			return record;
		}
	}

	@Override
	@Transactional(readOnly = false)
	public SysUserBind bindCreate(SysUserBind record) {
		record.setUpdateTime(DateUtil.date());
		record.setCreateTime(DateUtil.date());

		if (mSysUserBindMapper.insertSelective(record) <= 0) {
			throw new APIException("NOT_FIND", "账号已存在");
		} else {
			return record;
		}
	}

	@Override
	@Transactional(readOnly = false)
	public SysUserBind bindDelete(SysUserBind record) {
		ExampleWrapper example = ExampleWrapper.of(SysUserBind.class);
		example.and().andEqualTo("uuid", record.getUuid());

		if (mSysUserBindMapper.selectCountByExample(example) > 1) {
			example.and().andEqualTo("account", record.getAccount());

			if (mSysUserBindMapper.deleteByExample(example) <= 0) {
				throw new APIException("NOT_FIND", "账号不存在");
			} else {
				return record;
			}
		} else {
			throw new APIException("NOT_FIND", "绑定用户最少一个");
		}
	}

	@Override
	public List<SysUserBind> bindSelect(String uuid) {
		ExampleWrapper example = ExampleWrapper.of(SysUserBind.class);
		example.and().andEqualTo("uuid", uuid);
		example.excludeProperties("password");

		return mSysUserBindMapper.selectByExample(example);
	}

	@Override
	protected List<?> doPageQuery(PageParamUser param) {
		ExampleWrapper example = ExampleWrapper.of(clazz);
		example.selectProperties("sys_user.id", "sys_user.uuid", "sys_user.`name`", "sys_user.res_group", "g.name AS res_groupn", "sys_user.avatar");
		example.selectProperties("sys_user.phone", "sys_user.qq", "sys_user.email", "sys_user.create_time", "sys_user.update_time");
		example.selectProperties("GROUP_CONCAT( DISTINCT sys_user_group.`name` ) AS `group` ");
		example.selectProperties("GROUP_CONCAT( DISTINCT sys_user_role.`name` ) AS `role`");

		example.addJoinTable(ExampleJoin.left("sys_user_role_relation", "sys_user_role_relation.uuid = sys_user.uuid"));
		example.addJoinTable(ExampleJoin.left("sys_user_role", "sys_user_role_relation.identity = sys_user_role.identity"));

		example.addJoinTable(ExampleJoin.left("sys_user_group_relation", "sys_user_group_relation.uuid = sys_user.uuid"));
		example.addJoinTable(ExampleJoin.left("sys_user_group", "sys_user_group_relation.identity = sys_user_group.identity"));

		example.addJoinTable(ExampleJoin.left("sys_user_group AS g", "sys_user.res_group = g.identity"));

		example.setOrderByClause("sys_user_group_relation.isdefault DESC,sys_user_role_relation.isdefault DESC");
		example.setGroupByClause("sys_user.uuid");

		example.and().andCondition("sys_user_role_relation.name LIKE ", criteriaLike(param, "name"));
		example.addHavingAnd("FIND_IN_SET('%s', GROUP_CONCAT(DISTINCT sys_user_role_relation.identity))", criteriaEqual(param, "role"));
		example.addHavingAnd("FIND_IN_SET('%s', GROUP_CONCAT(DISTINCT sys_user_group_relation.identity))", criteriaEqual(param, "group"));

		// 判断用户权限，如果用户权限有限，就只查看对应的用户组下的用户
		if (param != null && !PermissionUtil.isCanViewAllData(param)) {
			example.and().andCondition(PermissionUtil.str(param, "sys_user."));
		}

		return mBaseMapper.selectJoinMap(example);
	}
}
